﻿
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;

namespace CommandLib
{
    /// <summary>
    /// Rabbit帮助类
    /// </summary>
    public class RabbitMqHelper : IDisposable
    {
        private IConnectionFactory factory;
        private IConnection connection;
        private IModel channel;
        private IBasicProperties BasicProperties;
        private string _exchangeName;
        /// <summary>
        /// 过期时间/秒，为0永不过期
        /// </summary>
        private ulong outTime = 0;
        /// <summary>
        /// 是否连接
        /// </summary>
        public bool IsConnection { get; private set; }
        public RabbitMqHelper(MqModels mqModels)
        {
            factory = new ConnectionFactory//创建连接工厂对象
            {
                //IP地址
                HostName = mqModels.HostName,
                //端口号
                Port = mqModels.Port,
                //用户账号
                UserName = mqModels.UserName,
                //用户密码
                Password = mqModels.Password,
                //虚拟主机
                VirtualHost = mqModels.VirtualHost,
                //自动重连
                AutomaticRecoveryEnabled = mqModels.AutomaticRecoveryEnabled,
                //心跳15秒
                RequestedHeartbeat = TimeSpan.FromSeconds(15),
            };
            //创建连接对象
            connection = factory.CreateConnection();
            IsConnection = connection.IsOpen;
            //创建连接会话对象
            channel = connection.CreateModel();
            //过期时间
            outTime = mqModels.MqQueueOutTime;


        }
        /// <summary>
        /// 连接
        /// </summary>
        /// <returns></returns>
        public bool Connection()
        {
            try
            {
                //创建连接对象
                connection = factory.CreateConnection();
                channel = connection.CreateModel();
                IsConnection = connection.IsOpen;
            }
            catch (Exception)
            {
                throw;
            }
            return IsConnection;

        }
        /// <summary>
        /// 工作队列模式
        /// </summary>
        /// <param name="exchangeName"></param>
        /// <param name="queueName"></param>
        public void ExchangeWork(string exchangeName, string queueName)
        {
            _exchangeName = exchangeName;
            //绑定交换机
            channel.ExchangeDeclare(exchangeName, ExchangeType.Direct);
            //绑定队列名
            channel.QueueDeclare(queueName, durable: true, false, false, null);
            //绑定exchanges 和Queues                  
            channel.QueueBind(queueName, exchangeName, "", null);


        }


        /// <summary>
        /// 发送工作队列数据
        /// </summary>
        /// <param name="Message"></param>
        public void WorkSend(string Message)
        {
            if (!Message.IsEmpty())
            {
                var body = Encoding.UTF8.GetBytes(Message);
                var properties = channel.CreateBasicProperties();
                //消息持久化
                properties.Persistent = true;
                channel.BasicPublish(exchange: _exchangeName, routingKey: "", mandatory: false, basicProperties: properties, body: body);
            }

        }


        /// <summary>
        /// 持久化发部广播
        /// </summary>
        /// <param name="exchangeName"></param>
        public void ExchangeFanout(string exchangeName)
        {
            _exchangeName = exchangeName;
            BasicProperties = channel.CreateBasicProperties();
            //执久化
            BasicProperties.DeliveryMode = 2;
            //把交换机设置成fanout发布订阅模式
            channel.ExchangeDeclare(_exchangeName, type: ExchangeType.Fanout, true, false);

        }
        /// <summary>
        /// 广播订阅
        /// </summary>
        public void ExchangeSubscribe(string queueName, string exchangeName)
        {

            //声明交换机
            channel.ExchangeDeclare(exchangeName, ExchangeType.Fanout, true);

            if (outTime != 0)
            {
                //声明队列，设置过期时间
                channel.QueueDeclare(queueName, true, false, false, new Dictionary<string, object> { { "x-message-ttl", outTime * 1000 } });
            }
            else
            {
                //声明队列
                channel.QueueDeclare(queueName, true, false, false, null);
            }

            //将队列与交换机进行绑定
            channel.QueueBind(queueName, exchangeName, "", null);
        }
        /// <summary>
        /// 接收发部消息
        /// </summary>
        public void MessageReceived(EventHandler<BasicDeliverEventArgs> eventHandler)
        {
            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += eventHandler;
        }
        /// <summary>
        /// 接收队列消息
        /// </summary>
        /// <param name="eventHandler"></param>
        /// <param name="queueName"></param>
        public void QueueMessageReceived(EventHandler<BasicDeliverEventArgs> eventHandler, string queueName)
        {            
            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += eventHandler;
            channel.BasicConsume(queueName, true, consumer);
        }

        /// <summary>
        /// 发部广播消息数据
        /// </summary>
        /// <param name="data"></param>
        public void SendData(string data)
        {
            //消息内容
            byte[] body = Encoding.UTF8.GetBytes(data);
            //发布消息,
            channel.BasicPublish(_exchangeName, "", BasicProperties, body);
        }
        /// <summary>
        /// 资源回收
        /// </summary>
        public void Dispose()
        {
            channel?.Dispose();
            connection?.Close();
            connection?.Dispose();

        }
    }
}
